/*
 *  Ship.h
 *  Pirates!
 *
 *  Created by Alan Dorin on 12/02/11.
 *  Copyright 2007 __MyCompanyName__. All rights reserved.
 *
 */

#ifndef _SHIP_H_
#define _SHIP_H_

#include "SimpleVector.h"
#include "Globals.h"

class AIController;

#include <iostream>

class Ship
{		
	private:
		long	position[3];				// grid indices (not continuous positions)
		SimpleVector	colour;
		long	uniqueId;
		long	rewardStored;				// amount of reward that has been collected on this bout
		long	damage;						// when damage gets to max. ship is "dead"
		long	maxDamage;
		bool	justDamagedFlag;			// true if this ship was damaged in the previous time step
		long	cannonRange;
		
		Globals::NeighbourDirection	aheadDirection;	// the direction of the ship's current heading
		Globals::ShipAction requestedAction;		// the action this ship is trying to perform in the current time step
		bool requestedActionSuccessFlag;			// flag set to show if the previously requested action was successful or not
		
		void setJustDamagedFlag(void);		// this flag is set automatically when the damage is applied in applyDamage()
		
		AIController* controller;			// pointer to the AI controller to be written by the students
		
	public:	
		Ship();
		// Ship(/*some params*/);
		Ship(const Ship& src);
		~Ship();
		
		void setControllerPtr(AIController* newController);
		
		void setPosition(long x, long y, long z);
		
		long getPositionX(void) const;
		long getPositionY(void) const;
		long getPositionZ(void) const;
		
		Globals::NeighbourDirection getAheadDirection(void) const;
		void setAheadDirection(Globals::NeighbourDirection newAheadDirection);

		long getCannonRange(void) const;

		void applyDamage(long damageSustained);
		long getDamage(void) const;
		long getMaxDamage(void) const;
		void clearJustDamagedFlag(void);
		bool justDamaged(void) const;
		
		bool isSunk(void) const;
		long getRewardStored(void) const;
		void addToRewardStored(long extraReward);
		void clearRewardStored(void);
		void setRequestedAction(Globals::ShipAction newAction);
		Globals::ShipAction getRequestedAction(void) const;
		void setRequestedActionSuccessFlag(bool newFlag);
		bool getRequestedActionSuccessFlag(void) const;
		
		bool checkMoveDirection(Globals::NeighbourDirection moveDirection);
		void makeMove(Globals::NeighbourDirection moveDirection);
		bool checkStationary();
		void makeStationary();
		
		Globals::ShipAction computeNextAction(void);
		
		long getId(void) const;
		void setId(long newId);
		
		void display(const SimpleVector& cellPosition, const SimpleVector& cellDimensions);
		Ship& operator= (const Ship& rhs);
		
		void debugOutput(std::ostream& outStream);
		void fileInput(ifstream& inFile);
		void fileOutput(ofstream& outFile);
		void outputStatistics(long curFrame);

		friend std::ostream& operator<< (std::ostream& outFile, const Ship& theShip);
		//friend istream& operator>> (istream& inFile, const Ship& theShip);
};

#endif
